/*
 * ClientNetworkInterface.java
 *
 * Created on October 9, 2006, 1:25 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package net.sf.iSnake.core;

import java.awt.Color;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.*;


/**
 *This handles the socket connection from client side.
 * @author Suraj
 *
 * Changes made by TLM on Jan 25, 2007
 * 1. removed the line "import net.sf.conf.MessageProtocol;"
 * 2. changed "package net.sf.client;" to "package net.sf.iSnake.core"
 * 3. Added getter and setter for "ClientNo"
 *
 */
public class ClientNetworkInterface extends Thread{
    private ISCP iscp;
    private Socket Soc=null;
    private boolean stop=false;
    private int Port;
    private int ClientNo;
    private InetAddress Server;
    private ObjectInputStream ois=null;
    private ObjectOutputStream oos=null;
    
    
    /**
     * Connects to the Server(localhost) at the specified port.
     * @param Port The Port number of server to the Connection is to be made.
     */
    public ClientNetworkInterface(int Port,ISCP iscp) {
        this.Port=Port;
        this.iscp = iscp;
        this.ClientNo = -1;
        
        //the server is at localhost
        try {
            this.Server=InetAddress.getByName(iscp.getConf().getServerNameForClient());
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        }
        this.start();
    }
    /** Connects to the specified Server at the specified port.
     * @param Port The Port number of server to the Connection is to be made.
     * @param Server Intaddress of the serever.
     */
    public ClientNetworkInterface(int Port,InetAddress Server,ISCP iscp) {
        this.Port=Port;
        this.iscp = iscp;
        this.ClientNo = -1;
        
        this.Server=Server;
        this.start();
    }
    public void run(){
        //Connects with the server
        try{
            Soc = new Socket(Server,Port);
            Soc.setTcpNoDelay(true);
            //Connection Established With server.
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        //opens the Object I/O stream
        try{
            oos=new ObjectOutputStream(Soc.getOutputStream());
            ois=new ObjectInputStream(Soc.getInputStream());
            //Object i/o stream is opened
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
        //Receives the objects
        if(Soc.isConnected()){
            Object  obj=null;
            //reads this Client's no
//            System.out.println("inside cne: "+iscp.getGameController().getLocalSnake().getPlayer_id());
            System.out.println("inside cne: "+iscp.getGameController().getLocalSnake().toString());
            try {
                ClientNo=ois.readInt();
                iscp.getGameController().getLocalSnake().setPlayer_id(ClientNo);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            try {
                while( (obj=ois.readObject()) != null && !stop) {
                    // TODO receive the objects here and forward it
                    // send all the objects received to the gameController thread
                    iscp.getGameController().status(iscp.getGameController().DEBUG_LEVEL_MESSAGE,"Reading Object "+obj);
                    if(iscp.isPremode())    {
                        System.out.println("iscp.forwardReceivedISCPpacket(obj)");
                        iscp.forwardReceivedISCPpacket(obj);
                    }
                    else if(iscp.isPostmode()){
                        System.out.println("iscp.getGameController().updateGameFieldForPostMode(obj)");
                        iscp.getGameController().updateGameFieldForPostMode(obj);
                    }
                    
//                    iscp.getGameController().status(iscp.getGameController().DEBUG_LEVEL_MESSAGE,"Forwarding packet");
                }
            }
            catch(Exception ex) {
                //Server Unexpectedely Closed
//                if (ex.getMessage().equalsIgnoreCase("Connection Reset")) {
//                    iscp.getGameController().status(iscp.getGameController().DEBUG_LEVEL_ERROR,"Server closed unexpectedly. Connection Reset");
//                }
                iscp.getGameController().status(iscp.getGameController().DEBUG_LEVEL_MESSAGE,"Connection closed");
                System.out.println("Connection closed!");
                ex.printStackTrace();
            }
        }
    }
    
    /**
     *Send the Object to server.
     *@param obj The object to be send.
     */
    public void send(Object obj){
        try{
            oos.writeObject(obj);
            oos.flush();
            oos.reset();
        }
        catch(Exception e)        {
            e.printStackTrace();
        }
    }
    
    public void finalize (){
        try {Soc.close();}
        catch (IOException ex) {}
    }

    public int getClientNo() {
        return ClientNo;
    }

    public boolean isStop() {
        return stop;
    }

    public void setStop(boolean stop) {
        this.stop = stop;
    }

    public Socket getSoc() {
        return Soc;
    }
}